//---------------------------------------------------------------------
//  This file is part of the Background Motion solution.
// 
//  Copyright (C) Mindscape (TM).  All rights reserved.
//  http://www.mindscape.co.nz
// 
//  THIS CODE AND INFORMATION ARE PROVIDED AS IS WITHOUT WARRANTY OF ANY
//  KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
//  IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
//  PARTICULAR PURPOSE.
//---------------------------------------------------------------------

using System;
using System.Web.UI;
using System.Web.UI.WebControls;
using FlickrNet;

namespace Mindscape.BackgroundMotion.Website.Controls
{
  public partial class FlickrSearch : UserControl
  {
    private PhotoCollection _photos;
    private long _pages;
    private string _selectedId;
    private const int PHOTOS_PER_PAGE = 12;

    public delegate void PhotoSelectedDelegate(object sender, EventArgs e);
    public event PhotoSelectedDelegate PhotoSelected;

    protected void Page_Load(object sender, EventArgs e)
    {
    }

    /// <summary>
    /// Gets a value indicating whether there are currently photos in the result set
    /// </summary>
    /// <value>
    /// 	<c>true</c> if the result set has photos; otherwise, <c>false</c>.
    /// </value>
    protected bool HasPhotos
    {
      get
      {
        if (_photos != null && _photos.Count != 0)
        {
          return true;
        }
        else
        {
          return false;
        }
      }
    }


    /// <summary>
    /// Gets a value indicating whether this instance has no results (used for databinding the visibility of the
    /// "no results found" literal.
    /// </summary>
    /// <value>
    /// 	<c>true</c> if this instance has no results; otherwise, <c>false</c>.
    /// </value>
    protected bool HasNoResults
    {
      get
      {
        return !HasPhotos;
      }
    }

    /// <summary>
    /// Gets a value indicating whether we currently need paging.
    /// </summary>
    /// <value>
    /// 	<c>true</c> if more than one page is present; otherwise, <c>false</c>.
    /// </value>
    protected bool HasPaging
    {
      get
      {
        if (_pages > 1)
        {
          return true;
        }
        else
        {
          return false;
        }
      }
    }

    /// <summary>
    /// Handles the SelectedIndexChanged event on the paging control.
    /// </summary>
    /// <param name="sender">The source of the event.</param>
    /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
    protected void PagingList_SelectedIndexChanged(object sender, EventArgs e)
    {
      DoSearch(UserId.Text, Term.Text, Convert.ToInt32(PagingList.SelectedValue));
    }

    /// <summary>
    /// Handles the Click event of the SearchButton.
    /// </summary>
    /// <param name="sender">The source of the event.</param>
    /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
    protected void SearchButton_Click(object sender, EventArgs e)
    {
      NoResults.Visible = false;
      DoSearch(UserId.Text, Term.Text, 1);
    }

    /// <summary>
    /// Executes the search against Flickr
    /// </summary>
    /// <param name="userId">The user id.</param>
    /// <param name="term">The term.</param>
    /// <param name="page">The page.</param>
    private void DoSearch(string userId, string term, int page)
    {
      Flickr flickr = new Flickr();

      PhotoSearchOptions options = new PhotoSearchOptions();
      options.PerPage = PHOTOS_PER_PAGE;
      options.Page = page;

      if (userId.Trim().Length != 0)
      {
        try
        {
          FoundUser user = flickr.PeopleFindByUsername(userId); 
          options.UserId = user.UserId; 
        }
        catch (FlickrException)
        {
          Photos = null;
          Pages = 0;
          photosDataBinder.DataBind(this);
          return;
        }
      }
      
      if (term.Trim().Length != 0)
      {
        options.Text = term;
      }

      try
      {
        Photos allPhotos = flickr.PhotosSearch(options);
        Photos = allPhotos.PhotoCollection;
        Pages = allPhotos.TotalPages;
      }
      catch(FlickrException)
      {
        // do nothing, handling general connectivity issues that may occur 
        // this will result in "no results found" being displayed.
      }
      photosDataBinder.DataBind(this);
    }

    /// <summary>
    /// The number of pages currently in the result set
    /// </summary>
    public long Pages
    {
      set
      {
        // Some terms have massive numbers of results, prevent hanging browsers
        if (value > 20)
        {
          value = 20;
        }

        _pages = value;
        PagingList.Items.Clear();

        for(int i=0; i<value; i++)
        {
          PagingList.Items.Add(new ListItem((i + 1).ToString(), (i + 1).ToString()));
        }
      }
      get { return _pages; }
    }


    /// <summary>
    /// The result set of Photo instances retrieved from a search
    /// </summary>
    public PhotoCollection Photos
    {
      get { return _photos; }
      set { _photos = value; }
    }

    /// <summary>
    /// Gets or sets the currently selected photo id
    /// </summary>
    public string SelectedId
    {
      get { return _selectedId; }
      set { _selectedId = value; }
    }

    /// <summary>
    /// Handle a Photo selection by setting the SelectedId property and returning control and raising an event to indicate this has occured
    /// </summary>
    /// <param name="sender">The source of the event.</param>
    /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
    protected void Photo_Click(object sender, EventArgs e)
    {
      SelectedId = ((ImageButton)sender).Attributes["photoid"];

      FlickrPopup.Hide();

      if (PhotoSelected != null)
        PhotoSelected(this, null);
    }
  }
}